<!--
 * @Author       : wfl
 * @LastEditors  : wfl
 * @description  :
 * @updateInfo   :
 * @Date         : 2023-08-11 11:14:57
 * @LastEditTime : 2023-09-25 17:11:15
-->
<script setup lang="ts" name="FormConfig">
import { Plus, Search } from '@element-plus/icons-vue'
import { ElInput, ElMessageBox } from 'element-plus'
import { IkingPicker } from 'iking-web-ui'
import { EFlowFormType } from '@main/views/approve-workflow/enum'
import { useLinear } from '@main/views/approve-workflow/useLinear'
import { useLoadEditData } from '../load-edit-data'
import NewFormModal from './components/NewFormModal.vue'
import BaseModalSort from './components/BaseModalSort.vue'
import BaseModalMove from './components/BaseModalMove.vue'
import BaseModalCopy from './components/BaseModalCopy.vue'
import OrgItems from '@/MainApp/views/approve-workflow/WorkFlow/OrgItems.vue'
import { formApi } from '@/MainApp/apis/approve-center'

interface IForm {
  id?: string
  name: string // 表单名称
  icon: string // 表单图标
  groupId: string // 表单所属分组编号
  groupName: string // 表单所属分组名称
  remark: string // 表单说明
  status: 'ENABLE' | 'DISABLE' // 表单状态 可用值ENABLE,DISABLE	string
  statusName: string // 表单状态名称
  customizeInitiator: string // 表单是否支持配置发起人
  __hidden?: boolean // 是否展开
}

interface IList {
  deletable: boolean // 分组是否允许删除
  formCount: number // 分组下表单数量，页面展示时使用，新增或更新时忽略
  forms: IForm[] // 工作流表单基础配置信息
  id?: string
  name: string // 分组名称
  remark: string // 分组说明
  renamable: boolean // 分组是否允许重命名
  sortOrder: number
  sortable: boolean // 分组是否允许排序
  updateBy?: string
  updateName?: string
  updateTime?: string
  __hidden?: boolean // 是否展开
}

const { msgSuccess, msgError, msgBoxWarnAsync } = useMessage()
const { baseUrl } = useHttpUrl()
const token = useToken()

const router = useRouter()
const searchText = ref('')
const state: { forms: IList[]; } = reactive({
  forms: []
})

// 查询
const loading = ref(false)
const showSkeleton = ref(true)
const getFormInfo = async () => {
  loading.value = true
  const param = {
    initiatorViewOnly: false,
    name: searchText.value
  }
  const { success, data } = await useGroup(param)
  if (success) {
    showSkeleton.value = false
    state.forms = data.map((v: any) => {
      return {
        ...v,
        __hidden: false
      }
    })
  }
  loading.value = false
}
getFormInfo()

const groupName = ref('')
const errorText = ref('')
// Box通用配置
const MSG_CONFIG = {
  confirmButtonText: '确定',
  cancelButtonText: '取消',
  showInput: false,
  message: () => h('div', { className: 'ik-msg-box-error' }, [
    h(ElInput, {
      modelValue: groupName.value,
      clearable: true,
      maxLength: 12,
      placeholder: '请输入分组名称',
      'onUpdate:modelValue': value => {
        if (!value.trim())
          errorText.value = '请输入分组名称'
        else
          errorText.value = ''
        groupName.value = value
      }
    }),
    h('p', { className: 'ik-msg-box-error-transition', innerHTML: errorText.value })
  ]),
  draggable: true
}

// 新建分组
const handCreateGroup = () => {
  ElMessageBox.prompt('', '新建分组', {
    ...MSG_CONFIG,
    beforeClose: async (action, instance, done) => {
      if (action === 'confirm') {
        if (!groupName.value.trim()) {
          errorText.value = '请输入分组名称'
          return
        }

        instance.confirmButtonLoading = true
        const check = await formApi.checkGroupName({
          name: groupName.value,
          id: ''
        })
        if (!check.success) {
          errorText.value = check.msg
          msgError(check.msg)
          instance.confirmButtonLoading = false
          return
        }
        const { success, msg } = await formApi.createGroup({
          name: groupName.value
        })
        if (success) {
          groupName.value = ''
          msgSuccess(msg)
          done()
          getFormInfo()
        }
        else {
          msgError(msg)
        }
      }
      else {
        errorText.value = ''
        done()
      }
      instance.confirmButtonLoading = false
    }
  }).catch(() => {})
}
// 重命名
const handRename = (item: IList) => {
  (ElMessageBox.prompt as any)('', `重命名[${item.name}]`, {
    ...MSG_CONFIG,
    confirmButtonText: '重命名',
    inputValue: item.name,
    beforeClose: async (action: string, instance: any, done: () => void) => {
      if (action === 'confirm') {
        instance.confirmButtonLoading = true
        const check = await formApi.checkGroupName({
          id: item.id!,
          name: groupName.value
        })
        if (!check.success) {
          instance.inputErrorMessage = check.msg
          msgError(check.msg)
          instance.confirmButtonLoading = false
          return
        }
        const { success, msg } = await formApi.renameGroup({
          id: item.id!,
          name: groupName.value
        })
        if (success) {
          msgSuccess(msg)
          done()
          getFormInfo()
          groupName.value = ''
        }
        else {
          msgError(msg)
          instance.confirmButtonLoading = false
        }
      }
      else {
        done()
      }
      instance.confirmButtonLoading = false
    }
  }).catch(() => {})
}

// 删除
const handDelete = async ({ id }: IList) => {
  msgBoxWarnAsync(
    '删除分组',
    '删除分组后，该分组下的表单将会被移动到默认分组下，是否继续？',
    async () => {
      const { success, msg } = await formApi.deleteGroup(id!)
      if (success) {
        msgSuccess(msg)
        getFormInfo()
      }
      else {
        msgError(msg)
      }
    }
  )
}

// == 排序==
const showSort = ref(false)
const sortData: Ref<any> = ref([])
const sortType = ref('group')
const sortTitle = ref('分组排序')
// 排序
const handSort = (type: string, item?: IList) => {
  sortType.value = type
  if (type === 'group') {
    sortTitle.value = '分组排序'
    sortData.value = state.forms
  }
  else {
    sortTitle.value = '表单排序'
    sortData.value = item?.forms
  }
  showSort.value = true
}

// 复制模板dialog
const showCopy = ref(false)
// 表单相关
const formVisible = ref(false)
// 新建表单type
const handCreateForm = (type: string) => {
  formVisible.value = false
  if (type === EFlowFormType.已有模板) {
    showCopy.value = true
    sortData.value = state.forms
  }
  else {
    router.push({ name: 'EditForm', query: { type } })
  }
}

// const loadingEdit = ref(false);
const { loadingEdit } = useLoadEditData()

const showPicker = ref(false)
const refIkingPicker: Ref<null | { handClear: Function; }> = ref(null)
const handList: Ref<Array<any>> = ref([])
const handId = ref()
const handSelected = async (val: { list: any[]; }) => {
  handList.value = val.list.map((had: any) => {
    const {
      elementName: initiatorName,
      elementId: initiatorId,
      elementType: initiatorType
    } = had
    return {
      ...had,
      initiatorName,
      initiatorId,
      initiatorType
    }
  })
  const param = {
    formId: handId.value,
    initiators: handList.value?.length
      ? handList.value
      : [
          {
            initiatorType: 'ALL'
          }
        ]
  }
  const { success, msg } = await formApi.editInitiator(param)
  if (success) {
    msgSuccess(msg)
    getFormInfo()
  }
  else {
    msgError(msg)
  }
  refIkingPicker.value?.handClear()
}

enum EStatu {
  停用 = 'DISABLE',
  启用 = 'ENABLE'
}
// 移动 - 启用
const showMove = ref(false)
const chooseGroup: Ref<any | null> = ref(null)
watch(
  () => showMove.value,
  (bool: Boolean) => {
    if (!bool)
      chooseGroup.value = null
  }
)
// 启、停用
const handBlockUp = async (row: any) => {
  const { status, id } = row
  const stop = status !== EStatu.停用
  if (stop) {
    msgBoxWarnAsync(
      '确认停用表单吗？',
      '停用的表单会被放到 「停用」 分组中',
      async () => {
        const { success } = await formApi.blockUp(id)
        if (success)
          getFormInfo()
      }
    )
  }
  else {
    showMove.value = true
    chooseGroup.value = row
  }
}
const handMove = async (row: any) => {
  chooseGroup.value = row
  showMove.value = true
}
// 修改发起人
const handEditInitiator = (row: any) => {
  showPicker.value = true
  handId.value = row.id
  handList.value = row.initiators.map((initiator: any) => {
    const { initiatorId, initiatorName, initiatorType } = initiator
    return {
      ...initiator,
      elementName: initiatorName,
      elementId: initiatorId,
      elementType: initiatorType
    }
  })
}

const handDeleteDta = (row: any) => {
  msgBoxWarnAsync('删除确认', `确认删除表单【${row.name}】吗？`, async () => {
    const { success } = await formApi.deleteForm(row.id)
    if (success)
      getFormInfo()
  })
}

const isAllUser = (row: any) => {
  return (
    row.initiators?.length === 1 && row.initiators[0].initiatorType === 'ALL'
  )
}
// const handToogle = (item: any) => {
//   item.__hidden = !item.__hidden
// }

const { getLinearGradient } = useLinear()
</script>

<template>
  <IkPageFull header-title="表单管理" :refresh-btn="false" :setting-btn="false">
    <template #headerRight>
      <div class="flow-card-header">
        <ElInput
          v-model.trim="searchText"
          placeholder="输入表单名称,回车搜索"
          :prefix-icon="Search"
          @keyup.enter="getFormInfo"
        />
        <el-button @click="handCreateGroup">新建分组</el-button>
        <el-button @click="handSort('group')">分组排序</el-button>
        <el-button type="primary" @click="formVisible = true">
          <el-icon>
            <Plus />
          </el-icon>
          创建表单
        </el-button>
      </div>
    </template>
    <template #table>
      <el-card class="h-full iflow-box-card overflow-overlay" shadow="never">
        <template v-if="loading && showSkeleton">
          <el-skeleton :rows="5" animated />
          <el-skeleton :rows="5" animated />
        </template>
        <template v-else>
          <IkCollapseCard v-for="item in state.forms" :key="item.id" v-model="item.__hidden">
            <template #header-leaft>
              <div class="card-header">
                <span>
                  {{ item.name }}
                  <span class="inline-block ml-[5px]">
                    ({{ item.formCount }})
                  </span>
                </span>
              </div>
            </template>
            <template #header-right>
              <el-button
                v-if="item.renamable"
                link
                @click="handRename(item)"
              >
                <template #icon>
                  <IkSvgIcon
                    name="iksvg_bianji"
                  />
                </template>
                重命名
              </el-button>
              <el-button
                v-if="item.deletable"
                class="danger"
                link
                @click="handDelete(item)"
              >
                <template #icon>
                  <IkSvgIcon
                    class="mt-[-1px]"
                    name="iksvg_shanchu"
                  />
                </template>
                删除
              </el-button>
              <el-button
                v-if="item.sortable"
                :disabled="item.forms.length < 2"
                link
                @click="handSort('form', item)"
              >
                <template #icon>
                  <IkSvgIcon
                    name="iksvg_paixu"
                  />
                </template>
                排序
              </el-button>
            </template>
            <el-table
              v-loading="loadingEdit"
              :data="item.forms"
              :show-header="false"
              style="width: 100%"
            >
              <el-table-column>
                <template #default="{ row }">
                  <div class="icon-name">
                    <div
                      class="form-icon"
                      :style="{ backgroundImage: getLinearGradient(row?.iconBackground) }"
                    >
                      <i :class="`ikflow ${row.icon}`"></i>
                    </div>
                    <div class="name">
                      <p>{{ row.name }}</p>
                      <p class="tip-text" :title="row.remark">
                        {{ row.remark }}
                      </p>
                    </div>
                  </div>
                </template>
              </el-table-column>
              <el-table-column>
                <template #default="{ row }">
                  <div class="name">
                    <p class="tip-text">发起人</p>
                    <div class="edit-btn">
                      <OrgItems
                        v-if="!isAllUser(row)"
                        v-model="row.initiators"
                        in-table
                        readonly
                      />
                      <p v-else>所有人</p>
                      <el-button
                        link
                        type="primary"
                        @click="handEditInitiator(row)"
                      >
                        修改
                      </el-button>
                    </div>
                  </div>
                </template>
              </el-table-column>
              <el-table-column width="120">
                <template #default="{ row }">
                  <div class="name">
                    <p class="tip-text">分类</p>
                    <p>{{ row.typeName || '--' }}</p>
                  </div>
                </template>
              </el-table-column>
              <el-table-column width="175">
                <template #default="{ row }">
                  <div class="name">
                    <p class="tip-text">最后更新</p>
                    <p>{{ row.updateTime }}</p>
                  </div>
                </template>
              </el-table-column>
              <el-table-column width="270" align="right">
                <template #default="{ row }">
                  <template v-if="row.manageByCurrentUser">
                    <div class="operate-btn">
                      <IkSvgIcon
                        name="iksvg_xiazai"
                        show-bg
                        pop
                        title="下载"
                      />
                      <IkSvgIcon
                        name="iksvg_xiugai"
                        show-bg
                        pop
                        title="编辑"
                        @click="router.push({
                          name: 'EditForm',
                          query: { type: row?.type, id: row.id, isEdit: 1 },
                        })"
                      />
                      <IkSvgIcon
                        :name="row.status === EStatu.启用 ? 'iksvg_zanting' : 'iksvg_bofang'"
                        show-bg
                        pop
                        :title="row.status === EStatu.启用 ? '停用' : '启用'"
                        @click="handBlockUp(row)"
                      />
                      <IkSvgIcon
                        v-if="row.status === EStatu.启用"
                        name="iksvg_paixu"
                        show-bg
                        pop
                        title="移动"
                        @click="handMove(row)"
                      />
                      <IkSvgIcon
                        v-else
                        name="iksvg_shanchu"
                        show-bg
                        pop
                        title="删除"
                        @click="handDeleteDta(row)"
                      />
                    </div>
                  </template>
                  <template v-else>
                    <OrgItems
                      v-if="row.managers?.length"
                      v-model="row.managers"
                      in-table
                      readonly
                      :show-icon="false"
                    >
                      <template #left>
                        <span class="tip-text">此表单由 </span>
                      </template>
                      <template #right>
                        <span class="tip-text">管理 </span>
                      </template>
                    </OrgItems>
                  </template>
                </template>
              </el-table-column>
            </el-table>
          </IkCollapseCard>
        </template>
      </el-card>
    </template>
  </IkPageFull>
  <NewFormModal v-model:formVisible="formVisible" @create="handCreateForm" />
  <BaseModalCopy v-model="showCopy" :data="sortData" />
  <BaseModalSort
    v-model="showSort"
    :type="sortType"
    :data="sortData"
    :title="sortTitle"
    @change="getFormInfo"
  />
  <BaseModalMove
    v-model="showMove"
    :data="chooseGroup"
    @requery="getFormInfo"
  />
  <IkingPicker
    ref="refIkingPicker"
    v-model="handList"
    v-model:show="showPicker"
    :api="{
      methods: 'post',
      url: `${baseUrl}/server/component/pick/mix`,
      headers: {
        'Content-Type': 'application/json;charset=UTF-8',
        'Authorization': token,
      },
    }"
    :tabs="['group', 'role', 'post']"
    :choose-type="['user', 'dep', 'role', 'post']"
    :type-option="{ dep: 'DEPT', user: 'USER', role: 'ROLE', post: 'POST' }"
    :prop-option="{
      name: 'elementName',
      id: 'elementId',
      type: 'elementType',
    }"
    @ok="handSelected"
  />
</template>

<style lang="scss" scoped>
.iflow-box-card {
  flex: 1;
  border-color: transparent;
  overflow-y: auto;

  & > :deep(.el-card__body){
    padding-top: 0;
    padding-bottom: 0;
  }

  p {
    padding: 0;
    margin: 0;
  }

  .icon-name {
    display: flex;

    .name {
      width: calc(100% - 61px);
    }
  }

  .edit-btn {
    display: inline-flex;
    margin-top: 10px;
  }

  .tip-text {
    color: var(--el-text-color-secondary);
    white-space: nowrap;

    /* 防止文本换行 */
    overflow: hidden;

    /* 隐藏超出元素框的文本 */
    text-overflow: ellipsis;

    /* 文本溢出时显示省略号 */
  }

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;

    span {
      font-weight: 600;
    }
  }

  .operate-btn .el-button {
    padding: 0;

    &:hover {
      color: var(--el-color-primary);
    }

    &.danger:hover {
      color: var(--el-color-danger);
    }
  }
}

.flow-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--el-text-color-regular);

  .el-input {
    width: auto;
    margin-right: var(--base-margin);
  }
}
</style>

<style lang="scss" scoped>
.form-icon {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #000;
  margin-right: 16px;

  i {
    color: #fff;
    font-size: 27px;
  }
}
</style>
